goal: compilation_unit {'1'} ;

#names

name:
	simple_name {'1'} 
	| qualified_name {'1'}
	;
simple_name : <IDENTIFIER> {'1' value asString};
qualified_name : name "." simple_name {'1', '.', '3'} ;

#file structure

compilation_unit:
	package_declaration_opt 'package'
	import_declaration_opt 'import'
	type_declaration_opt 'type' {package, import, type value asString}
	;
package_declaration_opt: package_declaration {'1', self newline} | {self empty};
package_declaration:
	"package" name ";" {'package: <', '2', '>'}
	;
import_declaration_opt: import_declarations {'1', self newline} | {self empty} ;
import_declarations:
	import_declarations import_declaration {'1', self newline, '2'}
	| import_declaration {'1'}
	;
import_declaration:
	"import" name ";" {'import <', '2', '>'}
	;
type_declaration_opt:
	type_declaration {'1'} | {self newline}
	;
type_declaration:
	"class" <IDENTIFIER> super_opt interfaces_opt class_body
	{'class', self newline, 'class-name <', '2' value asString, '>', self newline, 
	'3', '4', 'class-body <', '5', '>', self newline}
	;
super_opt:
	| "extends" name {'extends <', '2', '>', self newline}
	;
interfaces_opt:
	| "implements" interfaces {'implements <', '2', '>', self newline}
	;
interfaces:
	interfaces "," name {'1', ', ', '2'}
	| name {'1'}
	;
class_body:
	"{" class_body_declaration_opt "}" {'2'}
	;
class_body_declaration_opt:
	{self empty}
	| class_body_declarations {'1'}
	;
class_body_declarations:
	class_body_declarations class_body_declaration {'1', '2'}
	| class_body_declaration {'1'}
	;
class_body_declaration:
	method_declaration {'method: ', self newline, '1', self newline}
	| field_declaration {'field: ', self newline, '1', self newline}
	;
field_declaration:
	name <IDENTIFIER> "=" simple_statement ";" 
	{'field-type <', '1', '>', self newline, 'field-name <', '2' value asString, '>', self newline, 
	'field-body <', '4', '>'}
	;
method_declaration: 
	method_header method_body {'1', self newline, 'method-body <', '2', '>'}
	;
method_header: 
	method_header_declaration {'1'}
	| <COMMENT> method_header_declaration 
	{'comment <', '1' value asString, '>', self newline, '2'}
	;
method_header_declaration:
	name  <IDENTIFIER> "(" signature_declaration_opt ")"
	{'method-type <', '1' value asString, '>', self newline, 
	'method-name <', '2' value asString, '>', self newline, '4'}
	;
signature_declaration_opt: 
	signature_declaration {'1'} | {self empty}
	;
signature_declaration: 
	formal_parameter {'parameter <', '1', '>'}
	| signature_declaration "," formal_parameter {'1', self newline, 'parameter <', '3', '>'}
	;
formal_parameter: 
	name <IDENTIFIER> {'2' value asString, ': ', '1'}
	;
method_body:
	block {'1'}
	| ";" {'1' value asString}
	;
block :	
	"{" block_statements_opt "}" {'1' value asString, self newline, '2', self newline, '3' value asString}
	;
block_statements_opt :
	{self empty}
	| block_statements {'1'}
	;
block_statements :
	block_statement {'1'}
	| block_statements block_statement {'1', '2'}
	;
block_statement :
	simple_statement_opt {'1'}
	| block {'1'}
	;
simple_statement_opt:
	simple_statement ";" {'1', '2' value asString, self newline}
	| simple_statement block {'1', '2'}
	| <COMMENT> {'1' value asString}
	;
simple_statement: 
	simple_statement <NUMBER> {'1', self space, '2' value asString}
	| simple_statement <SYMBOL> {'1', self space, '2' value asString}
	| simple_statement "." {'1', self space, '2' value asString}
	| simple_statement "(" {'1', self space, '2' value asString}
	| simple_statement ")" {'1', self space, '2' value asString}
	| simple_statement "=" {'1', self space, '2' value asString}
	| simple_statement <STRING_LITERAL> {'1', self space, '2' value asString}
	| simple_statement <IDENTIFIER> {'1', self space, '2' value asString}
	| <NUMBER> {'1' value asString}
	| <IDENTIFIER> {'1' value asString}
	;